package com.sukmoonlee.dns.jWhois;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;


public class WhoisClient extends Thread {

	private String server_name="whois.iana.org";
	private int server_port=43;
	
	private String query_domain=null;
	
	private long time_start=0;
	private long time_end=0;
	public long time_elapsed=0;
	public int received_size=0;
	
	//private boolean flag_verbose=false;
	private boolean flag_redirect=true;
	//private boolean flag_whoisservers=true;
	//private boolean flag_raw=false;
	private boolean flag_display_redirect=false;
	
	public WhoisClient() {
		super();
	}
	
	public WhoisClient(String domain) {
		super();
		
		this.query_domain=domain;
	}
	
	public WhoisClient(String domain, String server) {
		super();
		
		this.query_domain=domain;
		this.server_name=server;
	}
	
	public WhoisClient(String domain, String server, int port) {
		super();
		
		this.query_domain=domain;
		this.server_name=server;
		this.server_port=port;
	}
	
	public String getQueryDomain() { return this.query_domain; }
	public void setQueryDomain(String name) { this.query_domain = name; }

	
	public String getServerName() {	return this.server_name; }
	public void setServerName(String name) { this.server_name = name; }

	public int getServerPort() { return this.server_port; }
	public void setServerPort(int port) { this.server_port=port; }
	
	//public void setFlagVerbose(boolean b) { this.flag_verbose=b; }
	public void setFlagRedirect(boolean b) { this.flag_redirect=b; }
	//public void setFlagWhoisServers(boolean b) { this.flag_whoisservers=b; }
	//public void setFlagRaw(boolean b) { this.flag_raw=b; }
	public void setFlagDisplayRedirect(boolean b) { this.flag_display_redirect=b; }
	
	public void run() {
		if(query_domain==null || "".equals(query_domain)) { return; }
		
		time_start=System.currentTimeMillis();
		
		Socket tcpSocket = null;
		
		StringBuffer output=new StringBuffer();
		String redirect_whois_server=null;
		String strTld = WhoisTools.parseTLD(query_domain);
		
		System.out.println("[Querying "+query_domain+"]");
		
		try	{
			//addr=InetAddress.getByName(server_name);			
			//tcpSocket = new Socket(addr, server_port);
			tcpSocket = new Socket(server_name, server_port);
			
			OutputStream os_socket = tcpSocket.getOutputStream();  
			InputStream is_socket = tcpSocket.getInputStream();
			
			String strCharset="utf-8";
			if("jp".equals(strTld)) { strCharset="iso-2022-jp"; }
			
			//System.out.println("charset: "+strCharset);
			
			BufferedWriter bufferW = new BufferedWriter(new OutputStreamWriter(os_socket));
			BufferedReader bufferR = new BufferedReader(new InputStreamReader(is_socket, strCharset));
			  
			if(server_name.indexOf("whois.verisign-grs.com")>=0) {
				bufferW.write("domain ");
			}
			bufferW.write(query_domain);
			bufferW.write("\r\n");
			bufferW.flush();
			
			while(true) {
				String str = bufferR.readLine();
				if(str==null) { break; }
				
				// Thin Whois Server (--- ignore a thick whois server)
				if("whois.iana.org".equals(server_name)) {
					if(str.length()>7 && str.indexOf("whois: ")==0) {
						redirect_whois_server=str.substring(7).trim();
					}
				} else if("whois.verisign-grs.com".equals(server_name)) {
					if(str.length()>17 && str.indexOf("   Whois Server: ")==0) {
						redirect_whois_server=str.substring(17).trim();
					}
				} else if("jobswhois.verisign-grs.com".equals(server_name)) {
					if(str.length()>17 && str.indexOf("   Whois Server: ")==0) {
						redirect_whois_server=str.substring(17).trim();
					}
				} else if("tvwhois.verisign-grs.com".equals(server_name)) {
					if(str.length()>17 && str.indexOf("   Whois Server: ")==0) {
						redirect_whois_server=str.substring(17).trim();
					}
				} else if("ccwhois.verisign-grs.com".equals(server_name)) {
					if(str.length()>17 && str.indexOf("   Whois Server: ")==0) {
						redirect_whois_server=str.substring(17).trim();
					}
				} else if(server_name.indexOf("whois.verisign-grs.com")>0) {
					if(str.length()>17 && str.indexOf("   Whois Server: ")==0) {
						redirect_whois_server=str.substring(17).trim();
					}
				}

				output.append(str);
				output.append("\n");
			}

			bufferW.close();
			bufferR.close();
			
			tcpSocket.close();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e)	{
			e.printStackTrace();
		}

		time_end=System.currentTimeMillis();
		time_elapsed=time_end-time_start;

		if(flag_redirect==true && redirect_whois_server!=null && !"".equals(redirect_whois_server)) {
			
			if(flag_display_redirect==true) {
				System.out.println("["+server_name+"] - "+time_elapsed+" msec");
				System.out.println(output);
			}
			System.out.println("[Redirected to "+redirect_whois_server+"] - "+time_elapsed+" msec");
			
			WhoisClient client=new WhoisClient(query_domain, redirect_whois_server);
			client.setFlagDisplayRedirect(flag_display_redirect);
			client.setFlagRedirect(flag_redirect);
			
			client.start();
			
		} else {
			System.out.println("["+server_name+"] - "+time_elapsed+" msec");
			System.out.println(output);
		}
	}
	
}